<?php
namespace Common\Model;
use Think\Model;
use Home\Service\ClockTimeService;
use Home\Service\AccountService;
// +----------------------------------------------------------------------
// | Date:2017年2月27日
// +----------------------------------------------------------------------
// | Author: EK_熊<1439527494@qq.com>
// +----------------------------------------------------------------------
// | Description: 此文件作用于 假期申请时，添加的审批人数据
// +----------------------------------------------------------------------
class ApproverModel extends Model{
    
    protected $baseOption = [];
    public function __construct(){
        parent::__construct();
        $this->baseOption = D('Options')->getOption('att_base',true);
        
    }

    /**
     * 审核通过的最终执行代码
     *
     * date:2017年2月22日
     * author: EK_熊
     */
    public function action_pass($appid,$approver_sn=''){
        $applyModel = M('Apply');
        $this->startTrans();
        
        //如果是后台管理员操作的话，
        if ($approver_sn == C('SYS_SN')) {
            
            $ret = $this->where(['apply_id'=>$appid,'app_status'=>0])->setField('app_status',1);
        }else{
            
            $ret = $this->where(['apply_id'=>$appid,'approver_sn'=>$approver_sn,'app_status'=>0])->setField('app_status',1);
            
        }
        
        $approverData = $this->where(['apply_id'=>$appid])->select();
        $approverCount = count($approverData);
        $passNum = 0;
        foreach ($approverData as $k=>$v){
            if ($v['app_status'] == 1) $passNum ++;
        }
        /*要全部审核数据都通过才能往下走*/
        if ($approverCount == $passNum){
            $ret = $this->_action_pass($appid);
            /* 修改申请数据的申请状态 */
            $applyModel->where(['id'=>$appid])->setField('status',1);
            /* 发送微信模板消息：通过 */
            $this->solve_send_msg($appid,1);
        }
        if (!$ret) {
            $this->rollback();
            $err = $this->getError();
            return false;
        }
        $this->commit();
        
        return true;
    }    
    
    
    
    
    /**
     * 审核结果，发送申请人
     * @param string $appid     申请id
     * @param unknown $retCode  状态值：1通过；2拒绝
     * @return boolean
     * date:2017年5月22日
     * author: EK_熊
     */
    public function solve_send_msg($appid='',$retCode){
        if (!$appid) return false;
        
        $result = "通过审批";
        $rejstr = '';
        if ($retCode == 2) {
            $result = "拒绝通过";
            $rejstr = D('Approver')->where(['apply_id'=>$appid,'app_status'=>2])->getField('reject_reason');
        }
        $appInfo = D('Apply')->where(['id'=>$appid])->field('sn,type,vacate_type,content')->find();
        $code = $appInfo['vacate_type'] ? $appInfo['vacate_type'] : $appInfo['type'];
        $typename = get_vacation_name_ch($code);
        $account = new AccountService();
        $user = $account->get_user_by_field(['sn'=>$appInfo['sn']],'wx_openid');
        $str = ['您好，你有一个申请已完成审批',$typename,$appInfo['content'],$result,$rejstr,date('Y-m-d H:i:s')];
        wx_send_msg_sys($user['wx_openid'], $user['ep_name'], $user['sn'], $str,'AgDzdUyYkQVFq00ylR5NZ6B2WekM7u4ZtNaNc7hnSIw',4,"$typename : $result");
    }
    
    
    
    /**
     * 审核执行类型区分中转站
     * @param unknown $appid
     * date:2017年4月19日
     * author: EK_熊
     */
    public function _action_pass($appid){
        $where['id'] = $appid;
        $appInfo = M('Apply')->where($where)->find();
        if (empty($appInfo['start_time']) && empty($appInfo['end_time'])) {
            $this->error = '申请数据错误！！';
            return false;
        }
        $appInfo['vacate_label'] = get_vacation_name_en($appInfo['vacate_type']);
        if ($appInfo['type'] == 1) {
            //外出类型
            if ($appInfo['vacate_type'] == 200){
                $ret = $this->solve_evection($appInfo);//短途
            }else{
                $ret = $this->solve_long_distance($appInfo);//长途
            }
        }elseif($appInfo['type'] == 2){
            //假期类型
            $vacationType = C('VACATION_TYPE_EN');
            $ret = $this->solve_vacation($appInfo,$vacationType[$appInfo['vacate_type']]);
        }elseif($appInfo['type'] == 3){
            if ($appInfo['vacate_type'] == 301) {
               //公休日加班 
                $ret = $this->solve_ot_weekend($appInfo);
            }else{
               //通宵加班类型
               $ret = $this->solve_ot_overnight($appInfo);
            }
        }elseif($appInfo['type'] == 4){
            //补打卡类型
            $ret = $this->solve_repair($appInfo);
        }elseif ($appInfo['type'] == 5){
            //通宵加班[系统提交]类型
            $ret = true;
        }
        
        return $ret;
    }
    
    
    
    /**
     * 统计未读消息数目
     * @param unknown $uid
     * date:2017年2月21日
     * author: EK_熊
     */
    public function count_msg_unread($sn){
        
        
        $where['app.approver_sn'] = $sn;
        $where['app.app_status'] = 0;
        $where['aly.status'] = 0;
        $join = ['__APPLY__ aly ON aly.id = app.apply_id'];
        $ret = $this->alias('app')->where($where)->join($join)->count();
        return $ret;
    }
    
    /**
     * 创建审核数据：最基础的必经节点，即上级领导数据
     * @param unknown $applyId
     * @param unknown $userInfo
     * @param unknown $days
     * @param unknown $message
     * date:2017年3月2日
     * author: EK_熊
     */
    public function approver_base($applyId,$userInfo){
        $account = new AccountService();
        $leader =  $account->get_approver_info($userInfo['sn'],'sn,ep_name');
        $add_base = [
            'sn'=>$userInfo['sn'],
            'created_time'=>CURRENT_TIME,
            'updated_time'=>CURRENT_TIME,
            'app_status'=>0,
            'apply_id'=>$applyId,
            'approver_sn'=>isset($leader['sn']) ? $leader['sn'] : '',
            'approver_name'=>isset($leader['ep_name']) ? $leader['ep_name'] : '',
        ];
        //如果没有领导,申请数据直接去到行政审核人
        if (!$leader) {
            $add_base = array_merge($add_base,$this->_app_cfg_admin('admin'));
        }
        return $add_base;
    }
    
    /**
     * 根据标签，从缓存配置信息获取审核人的工号，姓名
     * key:admin行政负责人(行政管理员)；admin_leader行政主管；hr人事管理员；boss老总
     * @param unknown $key
     * date:2017年4月19日
     * author: EK_熊
     */
    private function _app_cfg_admin($key){
        $leader = [
            'approver_name'=>$this->baseOption["$key"."_name"],
            'approver_sn'=>$this->baseOption["$key"."_sn"],
        ];
        return $leader;
    }
    
    
    
    /**
     * 创建审核人数据:外出类型
     * 流程：行政审核人，部门主管
     * @param unknown $applyId
     * @param unknown $userInfo
     * @param unknown $vcode
     * date:2017年2月28日
     * author: EK_熊
     */
    public function approver_leave($applyId,$userInfo,$days,$message){
        $add_base = $this->approver_base($applyId, $userInfo);
        if (!$add_base) return false;
        //行政审核人
        $add[]=array_merge($add_base,['approver_sn'=>$this->baseOption['admin_sn'],'approver_name'=>$this->baseOption['admin_name']]);
        $post = I('post');
        $intrval = strtotime($post['end_time'])-strtotime($post['start_time']);
        do{
            
            if (check_privilege(1) && $intrval < 86400 && $post['vacate_type'] == 200) {
                   //中心负责人考勤权 & 1天以内 &短途外出，符合以上3个条件不需要发送主管
                   break;
            }
            
            if (check_privilege(2)){
                $add[] = array_merge($add_base,$this->_app_cfg_admin('admin_leader'));
                break;
            }
            
            if ($add_base['approver_sn'] !== $this->baseOption['admin_sn']){
                $add[]=$add_base;//部门主管
            }
        }while(false);
        $this->addAll($add);
        
        //发送微信消息，通知行政审核人
        $this->approver_send_msg($applyId);
        return true;
    }
    
    /**
     * 创建审核人数据 : 假期类型
     * @param unknown $applyId
     * @param unknown $userInfo
     * @param unknown $days
     * @param unknown $message
     * @return boolean
     * date:2017年6月2日
     * author: EK_熊
     */
    public function approver_vacation($applyId,$userInfo,$days,$message){
        $add_base = $this->approver_base($applyId, $userInfo);
    
        if (!$add_base) return false;
        
        //行政审核人
        $add[]=array_merge($add_base,['approver_sn'=>$this->baseOption['admin_sn'],'approver_name'=>$this->baseOption['admin_name']]);
 
        
        $post = I('post');
        $intrval = strtotime($post['end_time'])-strtotime($post['start_time']);
        do{
            if (check_privilege(1) && $intrval < 86400) {
                   //中心负责人考勤权 & 1天以内 &短途外出，符合以上3个条件不需要发送主管
                   break;
            }
            
            if ($add_base['approver_sn'] !== $this->baseOption['admin_sn']){
                $add[]=$add_base;//部门主管
            }
        }while(false);
        $this->addAll($add);
    
        //发送微信消息，通知行政审核人
        $this->approver_send_msg($applyId);
        return true;
    }    
    
    
    /**
     * 创建审核人数据:加班
     * 流程：部门主管
     * 发消息：行政审核人
     * @param unknown $applyId
     * @param unknown $userInfo
     * @param unknown $vcode
     * date:2017年2月28日
     * author: EK_熊
     */
    public function approver_overtime($applyId,$userInfo,$message){
        $add_base = $this->approver_base($applyId, $userInfo);
        if (!$add_base) return false;
        
        //中心负责人考勤权 不需要发送主管
        if (check_privilege(1) && $message['total_day'] <= 1 && $message['type'] == 1) {
            $add_base = array_merge($add_base,$this->_app_cfg_admin('admin'));
        }
        $this->add($add_base);//部门主管
        
        return true;
    }    
    
    
    /**
     * 创建审核人数据:补打卡
     * 流程：部门主管
     * @param unknown $applyId
     * @param unknown $userInfo
     * @param unknown $vcode
     * date:2017年2月28日
     * author: EK_熊
     */
    public function approver_repair($applyId,$userInfo){
        
        $add_base = $this->approver_base($applyId, $userInfo);
        if (!$add_base) return false;
        $privilege_1 = check_privilege(1);
        if (($add_base['approver_sn'] !== $this->baseOption['admin_sn']) && !$privilege_1){
            $add[]=$add_base;//部门主管
        }

        $add[] = array_merge($add_base,$this->_app_cfg_admin('admin'));
        
        //部门主管
        $ret = $this->addAll($add);
        
        $this->approver_send_msg($applyId);//发送微信消息，通知行政管理员
        return $ret;
    }    
    
    
    
    
    /**
     * 发送微信模板消息，请假审核通知行政管理员
     * @param array $fromInfo
     * @param array $toInfo
     * @param unknown $appInfo
     * date:2017年3月27日
     * author: EK_熊
     */
    public function approver_send_msg($applyId){
        if (!isset($this->baseOption['admin_wx_openid'])) {
            return false;
        }
        $appInfo = M('Apply')->where(['id'=>$applyId])->find();
        $str = [
            0=>'您好,你有新的请假审批',
            1=>$appInfo['name'],
            2=>get_vacation_name_ch($appInfo['vacate_type']),
            3=>$appInfo['start_time'].' 至   '.$appInfo['end_time'],
            4=>time_hour_min_zh($appInfo['total_min']),
            5=>$appInfo['content'],
                    ];

        wx_send_msg_sys($this->baseOption['admin_wx_openid'], $this->baseOption['admin_name'], $this->baseOption['admin_sn'],$str, 't8Q2uaF0lJxhTcf4Gk8o5Eo-oAKCHp5w5dlsQ1S3ykY',1,'',C('HOST_NAME').U('Approver/index'));
    }
    
    
    /**
     * 如果直属领导是大boss，要发送消息通知 行政部门主管admin_leader
     * @param unknown $sn  直属领导的员工编号
     * date:2017年2月27日
     * author: EK_熊
     */
    public function notice_admin_leader($sn,$name,$message=[]){
        
        if ($sn == $this->baseOption['boss_sn']){
            $vcode = $message['type'] == 2 ? $message['vacate_type'] : $message['type'];
            $add = [
                'from_sn'=>$sn,
                'from_name'=>$name,
                'to_sn'=>$this->baseOption['admin_leader_sn'],
                'content'=>get_vacation_name_ch($vcode),
                'created_time'=>CURRENT_TIME,
                'isread'=>0,
                'type'=>$vcode,
                'start_time'=>$message['start_time'],
                'end_time'=>$message['end_time'],
            ];
        }
    }

 
    
    /**
     * 计算请假期间的正确，每天的开始结束时间，不考虑打卡时间点
     * @param unknown $appInfo
     * @param unknown $day
     * date:2017年5月5日
     * author: EK_熊
     */
    public function get_time_start_end($appInfo,$day){
        
        $day_app_s = date('Y-m-d',strtotime($appInfo['start_time']));
        $day_app_e = date('Y-m-d',strtotime($appInfo['end_time']));
        
        $time_start =  "$day 09:00:00";//初始的开始时间
        $time_end = "$day 18:00:00";
        //如果当前日期是请假的开始日期
        if ($day_app_s == $day) {
            $time_start = $appInfo['start_time'];
        }
        
        if ($day_app_e == $day){
            $time_end = $appInfo['end_time'];
        }
        if ($appInfo['end_time'] > "$day 06:00:00" && $appInfo['end_time'] < $time_start) {
            $time_start = "$day 06:00:00";
            $time_end = $appInfo['end_time'];
        }
        $appInfo['start_time'] = $time_start;
        $appInfo['end_time'] = $time_end;
//         return ['start_time'=>$time_start,'end_time'=>$time_end];
        return $appInfo;
    }
    
    
    /**
     * 审核操作: 公休日加班审批
     * @param unknown $appInfo
     * date:2018年3月30日
     * author: EK_熊
     */
    public function solve_ot_weekend($appInfo){
        
        //先检查申请当天是有打卡数据
        $attDayModel = M('AttendanceDay');
        $applyModel = D('Apply');
        //获取出差天数计算，有可能是一天，有可能是多天
        for ($i=0;$i<intval($appInfo['total_day']);$i++){
            $day = date('Y-m-d',(strtotime($appInfo['start_time'])+86400*$i));
            $dayNext =date('Y-m-d',(strtotime($day)+86400));
            
            $map_att['sn'] = $appInfo['sn'];
            $map_att['date'] = $day;
            $clocktime = $attDayModel->where($map_att)->field('duty_on,duty_off')->find();
            if ($clocktime) {
                //有打卡记录，组装打卡时间
                $clockService = new ClockTimeService($clocktime['duty_on'],$clocktime['duty_off']);
                $timeList = $applyModel->get_time_list_weekend($appInfo);
                $attInfo = $clockService->attendance_weekend($timeList);
                $attInfo['updated_time'] = CURRENT_TIME;
                $attDayModel->where(['sn'=>$appInfo['sn']])->save($attInfo);
            }
        }

        return true;
        
        
    }

    /**
     * 审核操作：通过，假期,病假，补休
     * 1.连续几天完整；2.半天；3.混合半天和连续几天
     * 只需要更新leave_前缀的字段，添加分钟数
     * @param unknown $appInfo
     * @param unknown $type
     * date:2017年2月23日
     * author: EK_熊
     */
    public function solve_vacation($appInfo,$type){
        
        $attDayModel = D('AttendanceDay');
        $applyModel = D('Apply');
        $attendanceInfo = [];
        //获取出差天数计算，有可能是一天，有可能是多天
        $dayInterval = diff_days($appInfo['start_time'],$appInfo['end_time']);
        for ($i=0;$i<$dayInterval;$i++){
            $day = date('Y-m-d',(strtotime($appInfo['start_time'])+86400*$i));
            //工作日检查
            $iswoekday = is_work_day($day);
            if (!$iswoekday) {
                continue;//非工作日，不做处理
            }
            //检查当天是否有数据
            $map_attday = ['sn'=>$appInfo['sn'],'date'=>$day];
            $isExist = $attDayModel->where($map_attday)->find();

            $applyTime = $this->get_time_start_end($appInfo, $day);

            $timelist = $applyModel->get_time_list($applyTime);
            $clockservice = new ClockTimeService($isExist['duty_on'],$isExist['duty_off']);
            $attenInfo = $clockservice->attendance_info($timelist);

            if (empty($isExist)){
                
                //创建信息数据
                $base_add = [
                    'name'=>$appInfo['name'],
                    'sn'=>$appInfo['sn'],
                    'date'=>$day,
                    'date_str'=>get_week($day),
                    'dep_id'=>$appInfo['dep_id'],//计算请假分钟数
                    'dep_name'=>$appInfo['dep_name'],//计算请假分钟数
                    'uid'=>$appInfo['uid'],//计算请假分钟数
                    'creaetd_time'=>CURRENT_TIME,
                ];
                $add = $base_add + $attenInfo;
                $ret = $attDayModel->add($add);
                if (!$ret) {
                    $this->error = "[$day]考勤记录添加失败！";
                    return false;
                }
            }else{

                $attenInfo['updated_time'] = CURRENT_TIME;
                $ret = $attDayModel->where($map_attday)->save($attenInfo);
                if (!$ret) {
                    $this->error = "[$day]考勤记录更新失败！";
                    return false;
                }
            }
         
        }
        //补休
        if ($type == 'leave_compensatory')  {
            $compenstory = $attDayModel->set_compensatory_consume($appInfo);
            if (!$compenstory) {
                $this->error = $attDayModel->getError();
                return false;
            }
        }
        //必须是待审核状态才执行年假，病假总数的扣除
        if ($appInfo['status'] == 0) {
            if (in_array($appInfo['vacate_type'],[109,103,110])) {
                $annualModel = D('AnnualLeave');
                //如果是年假类型，得修改年假剩余数
                $aply_created = date('Y-m-d',strtotime($appInfo['created_time']));
                $map_annual['sn']=$appInfo['sn'];
                $map_annual['start_date']=['elt',"$aply_created"];
                $map_annual['end_date']=['egt',"$aply_created"];
                $annualInfo = $annualModel->where($map_annual)->order('create_time desc')->field('(adjust-adjust_consume) as adjust_remain,id')->find();
                if ($type == 'leave_annual') {
                    $adjust_remain = intval($annualInfo['adjust_remain']);
    //                 $adjust_remain = $annualModel->where($map_annual)->order('create_time desc')->getField('(adjust-adjust_consume) as adjust_remain');
                    //先检查是否有调整值存在
                    if ($adjust_remain > 0 ){
                        if ($adjust_remain >= $appInfo['total_min']){
                            $anRet = $annualModel->where($map_annual)->order('create_time desc')->setInc('adjust_consume',$appInfo['total_min']);
                        }else{
                            $intrval = $appInfo['total_min']-$adjust_remain;
                            $anRet = $annualModel->where($map_annual)->order('create_time desc')->setInc('adjust_consume',$adjust_remain);
                            $anRet = $annualModel->where($map_annual)->order('create_time desc')->setInc('consume_min',$intrval);
                        }
                        
                    }else{
                        $anRet = $annualModel->where($map_annual)->order('create_time desc')->setInc('consume_min',$appInfo['total_min']);
                    }
                }
                
                if ($type == 'leave_sick_full') {
                    $anRet = $annualModel->where(['id'=>$annualInfo['id']])->setDec('sick_full_remain',$appInfo['total_min']);
                }
                if ($type == 'leave_sick_half') {
                    $anRet = $annualModel->where(['id'=>$annualInfo['id']])->setDec('sick_half_remain',$appInfo['total_min']);
                }
                
                if ($anRet == false && !$ret) {
                    $this->error = '数据异常，审批错误';
                    return false;
                }
            };
        }
        return true;
    }
    
    

    
    
    /**
     * 审核操作：通宵加班申请:审核通过
     * 
     * date:2017年3月31日
     * author: EK_熊
     */
    public function solve_ot_overnight($appInfo){
        //跨天通宵，把时间点切成两部分，前一天的下班时间是05:59:59，第二天的上时间是06：00
        $attDayModel = D('AttendanceDay');
        $workday_config = C('ACTUAL_WORK_DAY');
        $applyModel = D('Apply');
        
        $apply_start = strtotime($appInfo['start_time']);//加班开始时间
        $apply_end = strtotime($appInfo['end_time']);//加班结束时间
        
        $day_cur = get_day($apply_start);//申请加班的当天日期
        $day_next = date('Y-m-d',$apply_start+86400);//申请加班的第二天日期

        
        //第一天:把下班时间设置为了第二天的05：59:59，重建生成考勤数据
        $map['sn'] = $appInfo['sn'];
        $map['date'] = $day_cur;
        $actual_day_1 = $attDayModel->where($map)->field('duty_on,duty_off')->find();//第一天实际上打卡的时间
        
        $aply1_s = "$day_cur 20:00:00";//第一条加班申请的开始时间
        $aply1_e = $day_next.' '.$workday_config[1];//第一条加班申请的结束时间
        
        $apptime1 = array_merge($appInfo,['start_time'=>$aply1_s,'end_time'=>$aply1_e]);
        $timelist1 = $applyModel->get_time_list($apptime1);
        $clockService = new ClockTimeService($actual_day_1['duty_on'],$actual_day_1['duty_off']);
        $save_day1 = $clockService->attendance_info($timelist1);
        $save_day1['duty_off'] = $aply1_e;
        $save_day1['updated_time'] = CURRENT_TIME;
//         $update_cur_att = $attDayModel->where($map)->save($save_day1);
        dump($save_day1);
        //第二天:上班时间改为 06:00
        $map['date'] = $day_next;
        $actual_day_2 = $attDayModel->where($map)->field('duty_on,duty_off')->find();//第一天实际上打卡的时间
        
        $aply2_s = $day_next.' '.$workday_config[0];//第二条加班申请的开始打卡时间
        $aply2_e = $actual_day_2['duty_off'];//第二条加班申请的开始打卡时间
        
        $apptime2 = array_merge($appInfo,['start_time'=>$aply2_s,'end_time'=>$aply2_e]);
        $timelist2 = $applyModel->get_time_list($apptime2);
        $clockService = new ClockTimeService($actual_day_2['duty_on'],$actual_day_2['duty_off']);
        $save_day2 = $clockService->attendance_info($timelist2);
        $save_day2['duty_on'] = $aply2_s;
        $save_day2['updated_time'] = CURRENT_TIME;
        dump($save_day2);
//         $update_cur_att = $attDayModel->where($map)->save($save_day2);
        
        exit();
//         //如果结束点超过第二天的6点，设置第二天的上班时间是06:00:00，重新生成考勤数据
//         if ($appInfo['end_time'] > $workday_next_s) {
//             $map['date'] = $day_cur;
//             $att_next = $attDayModel->where($map)->find();
//             if (empty($att_next)) {
//                 //创建
//                 $clockService = new ClockTimeService($workday_next_s,$appInfo['end_time']);
//                 $attInfo = $clockService->attendance_info();
//                 $add = $attInfo+['duty_on'=>$workday_next_s,'duty_off'=>$appInfo['end_time']];
//                 $update_next_att = $attDayModel->add($add);
//             }else{
//                 //更新
                
//                 //要获取打卡点，是不是有比结束点还要晚的时间点
//                 $lastClicktime_day = date('Y-m-d',strtotime($appInfo['end_time']));
//                 $lastClicktime = M('Attendance')->where(['sn'=>$appInfo['sn'],'date'=>$lastClicktime_day])->order('recept_time desc')->getField('recept_time');
//                 $workday_next_e = $lastClicktime ? $lastClicktime : $appInfo['end_time'];
//                 $clockService = new ClockTimeService($workday_next_s,$workday_next_e);
//                 $attInfo = $clockService->attendance_info($timelist);

//                 $duty['duty_on'] = $workday_next_s;
//                 if ($appInfo['end_time'] > $att_next['duty_off']) $duty['duty_off'] =  $workday_next_e;
//                 $save = $attInfo+$duty;
//                 $map['date']=$day_next;
//                 $update_next_att = $attDayModel->where($map)->save($save);                
//             }
            
//             if (!$update_next_att) {
//                 $this->error = "[$day_next]数据处理失败！！";
//                 return false;
//             }
//         }
     return true;   
    }
    
    
    

    
    /**
     * 审核通过:补打卡
     * @param unknown $appInfo
     * date:2017年3月3日
     * author: EK_熊
     */
    public function solve_repair($appInfo){
        $repairtime = $appInfo['start_time'] ? $appInfo['start_time'] : $appInfo['end_time'];
        $clockService = new ClockTimeService($repairtime);
        $day = $clockService->day_cur;//根据当前的打卡点，获取正确的打卡日期
        $map_attday = ['sn'=>$appInfo['sn'],'date'=>$day];
        $attDayModel = D('AttendanceDay');
        $attDayInfo = $attDayModel->where($map_attday)->find();
        if ($attDayInfo && $appInfo['end_time'] && $attDayInfo['duty_off'] == $appInfo['end_time']) {
            return true;
        }
        if ($attDayInfo && $appInfo['start_time'] && $attDayInfo['duty_on'] == $appInfo['start_time']){
            return true;
        }
        $duty_on = $attDayInfo['duty_on'];
        $duty_off = $attDayInfo['duty_off'];
        if ($appInfo['start_time']) {
            $duty_on = $appInfo['start_time'];
        }else {
            $duty_off = $appInfo['end_time'];
        }
        if (empty($attDayInfo)) {
            $duty_time = $duty_on ? $duty_on : $duty_off;
            $clockService = new ClockTimeService($duty_time);
            $attendanceInfo = $clockService->attendance_info();
            //创建信息数据
            $base_add = [
                'name'=>$appInfo['name'],
                'sn'=>$appInfo['sn'],
                'date'=>$day,
                'date_str'=>get_week($day),
                'dep_id'=>$appInfo['dep_id'],//计算请假分钟数
                'dep_name'=>$appInfo['dep_name'],//计算请假分钟数
                'uid'=>$appInfo['uid'],//计算请假分钟数
                'creaetd_time'=>CURRENT_TIME,
                'duty_off'=>$duty_time,
                'duty_on'=>$duty_time
            ];
            $add = $base_add+$attendanceInfo;
            $ret = $attDayModel->add($add);
            if (!$ret) {
                $this->error = "[$day]考勤记录添加失败！";
                return false;
            }            
        }else{
            
            $clockService = new ClockTimeService($duty_on,$duty_off);
            //检查到有外出数据，需要获取外出的时间来计算考勤
            if ($attDayInfo['leave_evection']){
                $mapApp['sn']=$attDayInfo['sn'];
                $mapApp["DATE_FORMAT(`start_time`,'%Y-%m-%d')"]=['ELT',$day];
                $mapApp["DATE_FORMAT(`end_time`,'%Y-%m-%d')"]=['EGT',$day];
                $mapApp['type'] = 1;
                $applyInfoEve = M('Apply')->where($mapApp)->find();
                $attendanceInfo = $clockService->set_evection_min($applyInfoEve['start_time'], $applyInfoEve['end_time']);
            }
            
            $attendanceInfo = $clockService->attendance_info();
            
            //更新下班时间，和外出分钟数
            $attendanceInfo['duty_off'] = $duty_off;
            $attendanceInfo['duty_on'] = $duty_on;
            $attendanceInfo['date_str']=get_week($day);
            $ret = $attDayModel->where($map_attday)->save($attendanceInfo);
            if (!$ret) {
                $this->error = "[$day]考勤记录更新失败！";
                return false;
            }            
        }
        return true;
    }
    
    
    
    /**
     * 审核通过操作，短途出差
     * @param unknown $appInfo
     * date:2017年3月9日
     * author: EK_熊
     */
    public function solve_evection($appInfo){

        $attDayModel = D('AttendanceDay');
        $stamp_s = strtotime($appInfo['start_time']);
        $day = date('Y-m-d',$stamp_s);

        //重置方法执行时，需要检查是否和重置的日期一致
        $isresetday = $this->is_reset_day();
        if ($isresetday !== $day && $isresetday) {
            continue;
        }
        
        //检查当天是否考勤数据
        $map_attday = ['sn'=>$appInfo['sn'],'date'=>$day];
        $isExistAtt = $attDayModel->where($map_attday)->find();
        $timelist = D('Apply')->get_time_list($appInfo);
        $clockservice = new ClockTimeService($isExistAtt['duty_on'],$isExistAtt['duty_off']);
        $attenInfo = $clockservice->attendance_info($timelist);
        
        if (empty($isExistAtt)){
            //创建信息数据
            $base_add = [
                'name'=>$appInfo['name'],
                'sn'=>$appInfo['sn'],
                'date'=>$day,
                'date_str'=>get_week($day),
                'dep_id'=>$appInfo['dep_id'],//计算请假分钟数
                'dep_name'=>$appInfo['dep_name'],//计算请假分钟数
                'uid'=>$appInfo['uid'],//计算请假分钟数
                'creaetd_time'=>CURRENT_TIME,
            ];
            $add = $base_add+$attenInfo;

            $ret = $attDayModel->add($add);
            if (!$ret) {
                $this->error = "[$day]考勤记录添加失败！";
                return false;
            }
        }else{
            $attenInfo['updated_time'] = CURRENT_TIME;
            $ret = $attDayModel->where($map_attday)->save($attenInfo);
            if (!$ret) {
                $this->error = "[$day]考勤记录更新失败！";
                return false;
            }
        }
        return true;
    }
    

    
    /**
     * 长途出差
     * 1.只能申请 9:00 - 18:00 时间段的不同日期，(也就是必须大于一天)，即不存在半天的长途情况
     * 2.当天只能第二天以后的时间
     * 3.提交了长途申请且审核通过以后，清除申请时间范围产生的打卡数据
     * @param unknown $appInfo
     * @return boolean
     * date:2018年3月23日
     * author: EK_熊
     */
    public function solve_long_distance($appInfo){
        $attDayModel = D('AttendanceDay');
        //获取出差天数计算，有可能是一天，有可能是多天
        for ($i=0;$i<intval($appInfo['total_day']);$i++){
            $day = date('Y-m-d',(strtotime($appInfo['start_time'])+86400*$i));
            $dayNext =date('Y-m-d',(strtotime($day)+86400));
            //重置方法执行时，需要检查是否和重置的日期一致
            $isresetday = $this->is_reset_day();
            if ($isresetday !== $day && $isresetday) {
                continue;
            }
            //检查当天是否考勤数据
            $map_attday = ['sn'=>$appInfo['sn'],'date'=>$day];
            $isExist = $attDayModel->where($map_attday)->find();
        
            $applyTime = $this->get_time_start_end($appInfo, $day);
            $timelist = D('Apply')->get_time_list($applyTime);
            $clockservice = new ClockTimeService($isExist['duty_on'],$isExist['duty_off']);
            $attenInfo = $clockservice->attendance_info($timelist);
            if (empty($isExist)){
                //创建信息数据
                $add = [
                    'name'=>$appInfo['name'],
                    'sn'=>$appInfo['sn'],
                    'date'=>$day,
                    'date_str'=>get_week($day),
                    'dep_id'=>$appInfo['dep_id'],//计算请假分钟数
                    'dep_name'=>$appInfo['dep_name'],//计算请假分钟数
                    'uid'=>$appInfo['uid'],//计算请假分钟数
                    'creaetd_time'=>CURRENT_TIME,
                ];
                $add = $add+$attenInfo;
                $ret = $attDayModel->add($add);
                if (!$ret) {
                    $this->error = "[$day]考勤记录添加失败！";
                    return false;
                }
            }else{
                
                $attenInfo['updated_time'] = CURRENT_TIME;
                $ret = $attDayModel->where($map_attday)->save($attenInfo);
                if (!$ret) {
                    $this->error = "[$day]考勤记录更新失败！";
                    return false;
                }
            }
        }
        return true;        
    }
//     public function solve_long_distance($appInfo,$day){

//         $attDayModel = D('AttendanceDay');
//         $evectionCfg = get_evection_label($appInfo['vacate_type'],'label');
//         //获取出差天数计算，有可能是一天，有可能是多天
//         for ($i=0;$i<intval($appInfo['total_day']);$i++){
//             $day = date('Y-m-d',(strtotime($appInfo['start_time'])+86400*$i));
//             $dayNext =date('Y-m-d',(strtotime($day)+86400));
//             //重置方法执行时，需要检查是否和重置的日期一致
//             $isresetday = $this->is_reset_day();
//             if ($isresetday !== $day && $isresetday) {
//                 continue;
//             }
//             //检查当天是否考勤数据
//             $map_attday = ['sn'=>$appInfo['sn'],'date'=>$day];
//             $isExist = $attDayModel->where($map_attday)->find();
        
//             $applyTime = $this->get_time_start_end($appInfo, $day);
//             $clockService = new ClockTimeService($applyTime['on'],$applyTime['off']);
        
//             //长途类型的话，每天都是480
//             $total_min = 480;
        
//             if (empty($isExist)){
//                 //创建信息数据
//                 $add = [
//                     'name'=>$appInfo['name'],
//                     'sn'=>$appInfo['sn'],
//                     'date'=>$day,
//                     'date_str'=>get_week($day),
//                     $evectionCfg=>$total_min,//计算请假分钟数
//                     'dep_id'=>$appInfo['dep_id'],//计算请假分钟数
//                     'dep_name'=>$appInfo['dep_name'],//计算请假分钟数
//                     'uid'=>$appInfo['uid'],//计算请假分钟数
//                     'creaetd_time'=>CURRENT_TIME,
//                     'overtime'=>0,    //长途出差是不能用加班的
//                     'work_actual'=>480,
//                     'work_effect'=>480,
//                     'work_effect_918'=>480,
//                 ];
                
//                 $ret = $attDayModel->add($add);
//                 if (!$ret) {
//                     $this->error = "[$day]考勤记录添加失败！";
//                     return false;
//                 }
//             }else{
        
//                 $clockService = new ClockTimeService($isExist['duty_on'],$isExist['duty_off']);
//                 $save = $clockService->attendance_info();
//                 $save[$evectionCfg] = $total_min;
//                 $save['overtime'] = 0;
//                 $save['work_actual'] = 480;
//                 $save['work_effect'] = 480;
//                 $save['work_effect_918'] = 480;
//                 dump($save);
//                 exit();
//                 $ret = $attDayModel->where($map_attday)->save($save);
//                 if (!$ret) {
//                     $this->error = "[$day]考勤记录更新失败！";
//                     return false;
//                 }
//             }
//         }
//         return true;        
//     }
    
    
    
    /**
     * 对比上班和申请时间点，返回duty_on,duty_off,重新生成日常数据
     * @param unknown $click
     * @param unknown $alystart
     * @param unknown $alyend
     * date:2017年6月22日
     * author: EK_熊
     */
    public function contrast_aply_att($c1,$c2,$s1,$s2){
        
        //没有打卡记录的时候
        if (!$c1 && !$c2){
            return ['on'=>$s1,'off'=>$s2];
        }
        
        //只有一个打卡点的情况
        if ($c1 == $c2){
            if ($c1 <= $s1){
                $ret['on'] = $c1;
                $ret['off'] = $s2;
            }elseif($c1 >= $s2){
                $ret['on'] = $s1;
                $ret['off'] = $c1;
            }elseif($c1 > $s1 && $c1 < $s2){
                $ret['on'] = $s1;
                $ret['off'] = $s2;
            }
        }else{
            if (($c1 <= $s1 && $c2>=$s1 && $c2<=$s2) || ($c1<$s1 && $c2<=$s1)){
                $ret['on'] = $c1;
                $ret['off'] = $s2;
            }elseif(($c1>$s1 && $c1 <= $s2 && $c2 >= $s2) || ($c1>=$s2 && $c1>$s1)){
                $ret['on'] = $s1;
                $ret['off'] = $c2;
            }elseif ($c1 >= $s1 && $c2<=$s2 && $c1<=$s2){
                $ret['on'] = $s1;
                $ret['off'] = $s2;
            }elseif($c1<=$s1 && $c2 >= $s2){
                $ret['on'] = $c1;
                $ret['off'] = $c2;
            }
        }
        return $ret;
    }
    
    /**
     * 当前循环的日期，是否和手动重置的日期是同一天，如果不是同一天就跳过
     * 
     * date:2017年5月9日
     * author: EK_熊
     */
    public function is_reset_day(){
        $date_s = I('date_s');
        if ($date_s) {
            $days = I('days');
            $date_s = date("Y-m-d",strtotime($date_s)+86400*$days);
            return $date_s;
        }
//         return false;
        
    }
    
    /**
     * 传入日期，自动刷新当天的全部【已经通过】的申请数据，并且重建考勤数据
     * @param unknown $day
     * date:2017年6月2日
     * author: EK_熊
     */
    public function flush_all_apply_by_day($day){
        $applyModel = D('Apply');
        $approverModel =D('Approver');
        
        $map_apply['_string']="(`type`=4 AND DATE_FORMAT(end_time,'%Y-%m-%d')='$day') OR (DATE_FORMAT(start_time,'%Y-%m-%d') = '$day') OR (DATE_FORMAT(start_time,'%Y-%m-%d') <= '$day' AND DATE_FORMAT(end_time,'%Y-%m-%d') >= '$day')";
        $map_apply['status'] = 1;//必须是审核通过的数据才需要重新

        
        $ids = $applyModel->where($map_apply)->group('CONCAT(start_time,end_time)')->getField('id',true);//使用group+concat组合去除重复记录
        if ($ids) {
            foreach ($ids as $appid){
                $ret = $approverModel->_action_pass($appid);
                $errMsg[$appid] = "[{$appid}]申请数据重载完成！！";
                if (!$ret){
                    $errMsg[$appid] = "[$appid]错误：".$approverModel->getError();;
                }
                $deal_id[]=$appid;
            }
            if ($errMsg){
                $errMsg = implode('&#13;&#10;',$errMsg);
            }
        }
        return $errMsg;
    }
    
    
}